﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Threading;
using System.Net.Sockets;

namespace WebControlApp
{
    public partial class Main : Form
    {
        //private Controler form2;
        //private ControlerTest form3;
        private Network NetworkForm;
        //public JoystickInterface.Joystick jstForm1;
        //public string[] sticks;
        //public string currentStick;
        bool paintNow = false;
        bool CalibrationMode = false;
        int vertical = 0;
        int horizontal = 0;
        int pointOne = 0;
        int pointTwo = 800;
        int calibrationPoints = 12;
        double avgDistance = 8069.2;
        double[,] calibration = new double[3, 12] { { 10, 86, 145, 195, 232, 253, 265, 273, 279, 283, 288, 289 }, { 9, 12, 18, 24, 36, 48, 60, 72, 84, 96, 108, 120 }, { 899, 669, 450, 337, 227, 168, 136, 112, 97, 82, 76, 67 } }; 
        public string currentVideoConnection;
        public string currentCommandConnection;
        public string currentCommandPort;
        Pen redPen = new Pen(System.Drawing.Color.Red, 1);
        Pen greenPen = new Pen(System.Drawing.Color.Green, 1);
        Pen yellowPen = new Pen(System.Drawing.Color.Yellow, 1);
        Pen blackPen = new Pen(System.Drawing.Color.Black, 2);
        public Bitmap currentImage;
        TcpClient Client;
        Stream TcpStream;
        byte[] PacketData = new byte[11];


        
        
        
        

        private void calcDistance(int x, int y)
        {
            vertical = y;
            horizontal = x;

            if (vertical <= 600 && vertical >= 0 && horizontal <= 800 && horizontal >= 0)
            {
                int horz = 800 - horizontal;
                int vert = 600 - vertical;
                double distance = 0;
                double distanceFromCenter = 0;
                double turn=0;

                if (vert < calibration[0, 0] || vert > calibration[0, calibrationPoints - 1])
                {
                    distance = 0;
                    textBox1.Text = calibration[0, 0].ToString() + "," + calibration[0, calibrationPoints - 1].ToString() +"," + vert.ToString()+ ","+vertical.ToString();
                }
                else
                {
                    for (int i = 0; i<calibrationPoints-1; i++)
                    {
                        if (vert == calibration[0, i]) 
                        { 
                        distance = (int)calibration[1, i];
                        distanceFromCenter = (-(horz - 400) / ((avgDistance / distance) / 12));
                        turn = (Math.Atan(distanceFromCenter / distance)) * (180 / Math.PI);
                        i = calibrationPoints;
                        
                        }
                        else if(vert < calibration[0,i+1])
                        {
                            
                            distance = (calibration[1, i] + (vert - calibration[0, i]) * ((calibration[1, i + 1] - calibration[1, i]) / (calibration[0, i + 1] - calibration[0, i])));

                            
                            distanceFromCenter =( -(horz - 400) / ((avgDistance/distance)/12));

                            turn = (Math.Atan(distanceFromCenter / distance))*(180/Math.PI);
                            i = calibrationPoints;
                            textBox1.Text = Math.Round(distance, 6).ToString() + "." + Math.Round(distanceFromCenter, 6).ToString() + "," + Math.Round(turn, 6).ToString()+horz.ToString()+","+vert.ToString();
                        }

                    }

                }

                textBox3.Text = Math.Round(distanceFromCenter,2).ToString();
                textBox5.Text = Math.Round(distance,2).ToString();
                TurnDeg.Text =  Math.Round(turn,2).ToString();
                DistanceBar.Value = (int)distance;
                //TurnBar.Value = vert;
                
            }
           
        }
        
        private void GetNewPic()
        {
            byte[] buffer = new byte[100000];
            int read, total = 0;
            // create HTTP request

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(currentVideoConnection);
            // get respon se
            try
            {
                WebResponse resp = req.GetResponse();
                // get response stream

                Stream stream = resp.GetResponseStream();
                // read data from stream

                while ((read = stream.Read(buffer, total, 1000)) != 0)
                {
                    total += read;
                }
                // get bitmap

                Bitmap bmp = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, 0, total));
                Bitmap tmp = new Bitmap(bmp, 800, 600);
                stream.Close();
                resp.Close();
                toolStripStatusLabel4.Text = "Connected";
                DisplayNewPic(tmp);
            }
            catch (WebException Webe)
            {
                toolStripStatusLabel4.Text = Webe.Message;
            }
            
        }

        private void DisplayNewPic(Bitmap newpic)
        {
            A.BackgroundImage = newpic;
        }
        
        public Main()
        {
            InitializeComponent();
            //currentStick = null;
            button10.Enabled = false;
            currentCommandConnection = "192.168.2.101";
            currentVideoConnection = "http://192.168.2.101:8080/?action=snapshot";
            currentCommandPort = "31337";
            currentImage = new Bitmap(800, 600);
            A.BackgroundImage = currentImage;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //jstForm1 = new JoystickInterface.Joystick(this.Handle);
            //sticks = jstForm1.FindJoysticks();
            //scale all values in calbiration function
            Client = new TcpClient();
            
           
           
        }

        private void button8_Click(object sender, EventArgs e)
        {
            //form2 = new Controler();
            //form2.sticks = sticks;
           // form2.BringToFront();
           // form2.frm1 = this;
           // form2.Show();
        }

        private void button10_Click(object sender, EventArgs e)
        {
            //jstForm1.ReleaseJoystick();
            //form3 = new ControlerTest(currentStick);
            //form3.frm1 = this;
            //form3.BringToFront();
            //form3.Show();
            
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            
        }

        private void Form1_Activated(object sender, EventArgs e)
        {
            /*if (currentStick != null)
            {
                button10.Enabled = true;
                toolStripStatusLabel2.Text = currentStick;
            }
            else
            {
                button10.Enabled = false;
                toolStripStatusLabel2.Text = "None Selected";
            }*/
        }

        private void button9_Click(object sender, EventArgs e)
        {
            NetworkForm = new Network(currentVideoConnection ,currentCommandConnection);
            NetworkForm.frm1 = this;
            NetworkForm.BringToFront();
            NetworkForm.Show();

             //Network myNewNetwork = new Network();
            //myNewNetwork.Visible = true;
        }

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {

        }

        private void trackBar4_Scroll(object sender, EventArgs e)
        {
            textBox5.Text = ((int)(DistanceBar.Value*double.Parse(CPI.Text))).ToString();

        }

        private void trackBar2_Scroll(object sender, EventArgs e)
        {

        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void button11_Click(object sender, EventArgs e)
        {

        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
                        
        }

        private void UpdatePic_Tick(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(GetNewPic));
            t.Name = "Picture Fetching Thread";
            t.Start();

        }

        private void connect_Click(object sender, EventArgs e)
        {
            UpdatePic.Enabled = !UpdatePic.Enabled;
            try
            {
                Client.Connect(currentCommandConnection, int.Parse(currentCommandPort));
                TcpStream = Client.GetStream();
            }
            catch (SocketException Se)
            {
                toolStripStatusLabel4.Text = Se.Message;
            }
            catch (InvalidOperationException Ie)
            {
                toolStripStatusLabel4.Text = Ie.Message;
            }

            if (UpdatePic.Enabled == true) { toolStripStatusLabel4.Text = "Connected"; }
            else { toolStripStatusLabel4.Text = "Not Connected"; }
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            paintNow = true;
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            paintNow = false;
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (paintNow == true && CalibrationMode == false)
            {
                calcDistance(e.X, e.Y);
                A.Refresh();
            } else if(paintNow == true && CalibrationMode == true && checkBox1.Checked)
            {
                vertical = e.Y;
                horizontal = e.X;
                textBox5.Text = (600-e.Y).ToString();
                A.Refresh();
            }
            else if (paintNow == true && CalibrationMode == true && checkBox2.Checked)
            {
                vertical = e.Y;
                horizontal = e.X;

                if (horizontal < 400)
                {
                    pointOne = horizontal;
                }
                else if (horizontal > 400)
                {
                    pointTwo = horizontal;
                }
                textBox3.Text = (pointTwo - pointOne).ToString();
                textBox5.Text = horizontal.ToString();
                A.Refresh();

            }

        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if(CalibrationMode == false)
            {
                if (vertical >= calibration[0, calibrationPoints - 1])
            {
                e.Graphics.DrawLine(blackPen, horizontal, 0, horizontal, 600);
                e.Graphics.DrawLine(blackPen, 0, vertical, 800, vertical);
            }
            if (vertical >= 350)
            {
                e.Graphics.DrawLine(greenPen, horizontal, 0, horizontal, 600);
                e.Graphics.DrawLine(greenPen, 0, vertical, 800, vertical);
            }
            else if (vertical >= 257) 
            {
                e.Graphics.DrawLine(yellowPen, horizontal, 0, horizontal, 600);
                e.Graphics.DrawLine(yellowPen, 0, vertical, 800, vertical);
            }
            else if (vertical >= 238)
            {
                e.Graphics.DrawLine(redPen, horizontal, 0, horizontal, 600);
                e.Graphics.DrawLine(redPen, 0, vertical, 800, vertical);
            }
            else 
            {
                e.Graphics.DrawLine(blackPen, horizontal, 0, horizontal, 600);
                e.Graphics.DrawLine(blackPen, 0, vertical, 800, vertical);
            }
            }
            else if (CalibrationMode == true && checkBox1.Checked) e.Graphics.DrawLine(redPen, 0, vertical, 800, vertical);
            else if (CalibrationMode == true && checkBox2.Checked) 
                {
                    e.Graphics.DrawLine(redPen, pointOne, 0, pointOne, 600);
                    e.Graphics.DrawLine(redPen, pointTwo, 0, pointTwo, 600);
                }
                
        }

        private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
        {
            if (CalibrationMode == false)
            {
                calcDistance(e.X, e.Y);
                A.Refresh();
            }
        }

        private void button11_Click_1(object sender, EventArgs e)
        {
            openFileDialog1.InitialDirectory = Application.StartupPath;
            openFileDialog1.Title = "Please select file to store data file";
            openFileDialog1.FileName = "data.dat";
            openFileDialog1.ShowDialog();
        }

        private void button12_Click(object sender, EventArgs e)
        {
            saveFileDialog1.InitialDirectory = Application.StartupPath;
            saveFileDialog1.Title = "Please select file to store data file";
            saveFileDialog1.FileName = "data.dat";
            saveFileDialog1.ShowDialog();
        }
        private void OSC_Selected(object sender, TabControlEventArgs e)
        {
            if (e.TabPageIndex == 2)
            {
                CalibrationMode = true;
                label4.Text = "Pixels";
                label2.Text = "Pixel Width";

                DistanceMin.Text = calibration[1, 0].ToString();
                DistancePixMin.Text = calibration[0, 0].ToString();
                DistancePix12.Text = calibration[0, 1].ToString();
                DistancePix18.Text = calibration[0, 2].ToString();
                DistancePix24.Text = calibration[0, 3].ToString();
                DistancePix36.Text = calibration[0, 4].ToString();
                DistancePix48.Text = calibration[0, 5].ToString();
                DistancePix60.Text = calibration[0, 6].ToString();
                DistancePix72.Text = calibration[0, 7].ToString();
                DistancePix84.Text = calibration[0, 8].ToString();
                DistancePix96.Text = calibration[0, 9].ToString();
                DistancePix108.Text = calibration[0, 10].ToString();
                DistancePix120.Text = calibration[0, 11].ToString();

                AngleMin.Text = calibration[2, 0].ToString();
                Angle12.Text = calibration[2, 1].ToString();
                Angle18.Text = calibration[2, 2].ToString();
                Angle24.Text = calibration[2, 3].ToString();
                Angle36.Text = calibration[2, 4].ToString();
                Angle48.Text = calibration[2, 5].ToString();
                Angle60.Text = calibration[2, 6].ToString();
                Angle72.Text = calibration[2, 7].ToString();
                Angle84.Text = calibration[2, 8].ToString();
                Angle96.Text = calibration[2, 9].ToString();
                Angle108.Text = calibration[2, 10].ToString();
                Angle120.Text = calibration[2, 11].ToString();

                coeff.Text = avgDistance.ToString();




                

            }
        }

        private void OSC_Deselected(object sender, TabControlEventArgs e)
        {
            
            if (e.TabPageIndex == 2)
            {
                CalibrationMode = false;
                label4.Text = "Distance";
                label2.Text = "Turn Distance";
            }
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked == true) checkBox2.Checked = false;
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox2.Checked == true) checkBox1.Checked = false;
        }

        private void saveFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            FileStream fs;
            if(File.Exists(saveFileDialog1.FileName)){
            fs = new FileStream(saveFileDialog1.FileName, FileMode.Truncate);
            }
            else
            {
            fs = new FileStream(saveFileDialog1.FileName, FileMode.Create);
            }

            calibration[1, 0] = double.Parse(DistanceMin.Text.ToString());
            
            calibration[0, 0] = double.Parse(DistancePixMin.Text.ToString());
            calibration[0, 1] = double.Parse(DistancePix12.Text.ToString());
            calibration[0, 2] = double.Parse(DistancePix18.Text.ToString());
            calibration[0, 3] = double.Parse(DistancePix24.Text.ToString());
            calibration[0, 4] = double.Parse(DistancePix36.Text.ToString());
            calibration[0, 5] = double.Parse(DistancePix48.Text.ToString());
            calibration[0, 6] = double.Parse(DistancePix60.Text.ToString());
            calibration[0, 7] = double.Parse(DistancePix72.Text.ToString());
            calibration[0, 8] = double.Parse(DistancePix84.Text.ToString());
            calibration[0, 9] = double.Parse(DistancePix96.Text.ToString());
            calibration[0, 10] = double.Parse(DistancePix108.Text.ToString());
            calibration[0, 11] = double.Parse(DistancePix120.Text.ToString());

            calibration[2, 0] = double.Parse(AngleMin.Text.ToString());
            calibration[2, 1] = double.Parse(Angle12.Text.ToString());
            calibration[2, 2] = double.Parse(Angle18.Text.ToString());
            calibration[2, 3] = double.Parse(Angle24.Text.ToString());
            calibration[2, 4] = double.Parse(Angle36.Text.ToString());
            calibration[2, 5] = double.Parse(Angle48.Text.ToString());
            calibration[2, 6] = double.Parse(Angle60.Text.ToString());
            calibration[2, 7] = double.Parse(Angle72.Text.ToString());
            calibration[2, 8] = double.Parse(Angle84.Text.ToString());
            calibration[2, 9] = double.Parse(Angle96.Text.ToString());
            calibration[2, 10] = double.Parse(Angle108.Text.ToString());
            calibration[2, 11] = double.Parse(Angle120.Text.ToString());
            
            BinaryWriter wright = new BinaryWriter(fs);
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < calibrationPoints; j++)
                {
                    wright.Write(calibration[i, j]);
                }

            }
            
            double temp =0;

            for(int i = 0;i<calibrationPoints;i++)
            {
                temp = temp + (calibration[2, i] * calibration[1,i]);
            }
            avgDistance = temp / calibrationPoints;

            wright.Write(avgDistance);

            wright.Close();
            fs.Close();
        }

        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            if(File.Exists(openFileDialog1.FileName)){
            FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open);
            BinaryReader reader = new BinaryReader(fs);

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < calibrationPoints; j++) 
                {
                    calibration[i, j] = reader.ReadDouble();
                }

            }

            
            avgDistance = reader.ReadDouble();

            DistanceMin.Text = calibration[1, 0].ToString();
            DistancePixMin.Text = calibration[0, 0].ToString();
            DistancePix12.Text = calibration[0, 1].ToString();
            DistancePix18.Text = calibration[0, 2].ToString();
            DistancePix24.Text = calibration[0, 3].ToString();
            DistancePix36.Text = calibration[0, 4].ToString();
            DistancePix48.Text = calibration[0, 5].ToString();
            DistancePix60.Text = calibration[0, 6].ToString();
            DistancePix72.Text = calibration[0, 7].ToString();
            DistancePix84.Text = calibration[0, 8].ToString();
            DistancePix96.Text = calibration[0, 9].ToString();
            DistancePix108.Text = calibration[0, 10].ToString();
            DistancePix120.Text = calibration[0, 11].ToString();

            AngleMin.Text = calibration[2, 0].ToString();
            Angle12.Text = calibration[2, 1].ToString();
            Angle18.Text = calibration[2, 2].ToString();
            Angle24.Text = calibration[2, 3].ToString();
            Angle36.Text = calibration[2, 4].ToString();
            Angle48.Text = calibration[2, 5].ToString();
            Angle60.Text = calibration[2, 6].ToString();
            Angle72.Text = calibration[2, 7].ToString();
            Angle84.Text = calibration[2, 8].ToString();
            Angle96.Text = calibration[2, 9].ToString();
            Angle108.Text = calibration[2, 10].ToString();
            Angle120.Text = calibration[2, 11].ToString();

            coeff.Text = avgDistance.ToString();

            reader.Close();
            fs.Close();

            }
            

        }

        private void label21_Click(object sender, EventArgs e)
        {

        }

        private void textBox5_TextChanged(object sender, EventArgs e)
        {
            textBox8.Text = ((int)(Math.Abs(double.Parse(textBox5.Text)) * (double.Parse(CPI.Text)))).ToString();           
            if (double.Parse(textBox5.Text) < 0) { textBox7.Text = (-trackBar2.Value).ToString(); }
            else { textBox7.Text = (trackBar2.Value).ToString(); }
        }

        private void textBox8_TextChanged(object sender, EventArgs e)
        {

        }

        private void TurnDeg_TextChanged(object sender, EventArgs e)
        {
            textBox6.Text = Math.Round(Math.Abs(double.Parse(TurnDeg.Text))/double.Parse(DPC.Text),0).ToString();
            if (double.Parse(TurnDeg.Text) < 0) { textBox4.Text = (-trackBar1.Value).ToString(); }
            else { textBox4.Text = (trackBar1.Value).ToString(); }

        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            label6.Text = trackBar1.Value.ToString();
            textBox4.Text = trackBar1.Value.ToString();

        }

        private void trackBar2_Scroll_1(object sender, EventArgs e)
        {
            label5.Text = trackBar2.Value.ToString();
            textBox7.Text = trackBar2.Value.ToString();
        }

        private void label6_TextChanged(object sender, EventArgs e)
        {
            
        }

        private void textBox4_TextChanged(object sender, EventArgs e)
        {

        }

        private void button13_Click(object sender, EventArgs e)
        {
            PacketData[0] = byte.Parse(textBox2.Text); //command byte
            PacketData[1] = (byte) sbyte.Parse(textBox4.Text); //turn speed
            PacketData[2] = (byte)((int.Parse(textBox6.Text)>>8)& 0xFF); 
            PacketData[3] = (byte)(int.Parse(textBox6.Text) & 0xFF);      
            PacketData[4] = (byte) sbyte.Parse(textBox7.Text);
            PacketData[5] = (byte)((int.Parse(textBox8.Text)>>8)& 0xFF);
            PacketData[6] = (byte)(int.Parse(textBox8.Text) & 0xFF);
            PacketData[7] = (byte) sbyte.Parse(textBox9.Text);
            PacketData[8] =(byte)((int.Parse(textBox10.Text)>>8)& 0xFF);
            PacketData[9] =(byte)(int.Parse(textBox10.Text) & 0xFF);
            PacketData[10] =byte.Parse(textBox11.Text);

            TcpStream.Write(PacketData,0,11);

         }

        private void Main_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.T) 
            {
                PacketData[0] = byte.Parse(textBox2.Text); //command byte
                PacketData[1] = (byte) 0 ; //turn speed
                PacketData[2] = (byte) 0;
                PacketData[3] = (byte) 0;
                PacketData[4] = (byte) 1;
                PacketData[5] = (byte) 0;
                PacketData[6] = (byte) 10;
                PacketData[7] = (byte) 0;
                PacketData[8] = (byte) 0;
                PacketData[9] = (byte) 0;
                PacketData[10] =(byte) 0;

                TcpStream.Write(PacketData, 0, 11);
                textBox1.Text = textBox1.Text + "T";
            }
            else if (e.KeyData == Keys.G) 
            {
                PacketData[0] = byte.Parse(textBox2.Text); //command byte
                PacketData[1] = (byte)0; //turn speed
                PacketData[2] = (byte)0;
                PacketData[3] = (byte)0;
                PacketData[4] = (byte)sbyte.Parse("-1");
                PacketData[5] = (byte)0;
                PacketData[6] = (byte)10;
                PacketData[7] = (byte)0;
                PacketData[8] = (byte)0;
                PacketData[9] = (byte)0;
                PacketData[10] = (byte)0;

                TcpStream.Write(PacketData, 0, 11);
                textBox1.Text = textBox1.Text + "G";
            }
            else if (e.KeyData == Keys.F) 
            {
                PacketData[0] = byte.Parse(textBox2.Text); //command byte
                PacketData[1] = (byte)0; //turn speed
                PacketData[2] = (byte)sbyte.Parse("-1");
                PacketData[3] = (byte)0;
                PacketData[4] = (byte)10;
                PacketData[5] = (byte)0;
                PacketData[6] = (byte)0;
                PacketData[7] = (byte)0;
                PacketData[8] = (byte)0;
                PacketData[9] = (byte)0;
                PacketData[10] = (byte)0;

                TcpStream.Write(PacketData, 0, 11);
                textBox1.Text = textBox1.Text + "F";
            }
            else if (e.KeyData == Keys.H) 
            {
                PacketData[0] = byte.Parse(textBox2.Text); //command byte
                PacketData[1] = (byte)0; //turn speed
                PacketData[2] = (byte)1;
                PacketData[3] = (byte)0;
                PacketData[4] = (byte)10;
                PacketData[5] = (byte)0;
                PacketData[6] = (byte)0;
                PacketData[7] = (byte)0;
                PacketData[8] = (byte)0;
                PacketData[9] = (byte)0;
                PacketData[10] = (byte)0;

                TcpStream.Write(PacketData, 0, 11);
                textBox1.Text = textBox1.Text + "H";
            }

            }

        

      
       

  

       
     

      
    }
}
